import { IPSCodeListEditor, IPSEditor } from '@ibiz/dynamic-model-api';
import { IAppEditorHooks, IEditorControllerBase, IParam } from '../../../interface';
import { LogUtil, ModelTool, Util } from '../../../util';
import { AppEditorHooks } from '../../hooks';

export class EditorControllerBase implements IEditorControllerBase {
  /**
   * 父级项模型（表单项，表格项）
   *
   * @type {*}
   * @memberof EditorControllerBase
   */
  public parentItem!: any;

  /**
   * 构造 EditorControllerBase 实例
   *
   * @memberof EditorControllerBase
   */
  public constructor(opts: any) {
    this.initInputData(opts);
  }

  /**
   * 初始化输入数据
   *
   * @public
   * @memberof AppCtrlControllerBase
   */
  public initInputData(opts: IParam) {
    if (App.isPreviewMode() && opts.modelData) {
      this.editorInstance = opts.modelData;
    } else {
      this.editorInstance = opts.editorInstance;
    }
    this.context = opts.navContext;
    this.viewParam = opts.navParam;
    this.contextState = opts.contextState;
    this.contextData = opts.contextData;
    this.disabled = opts.disabled;
    this.parentItem = opts.parentItem;
    this.value = opts.value;
    this.modelService = opts.modelService;
  }

  /**
   * 编辑器模型
   *
   * @type {IPSEditor}
   * @memberof EditorControllerBase
   */
  public editorInstance!: IPSEditor;

  /**
   * 模型服务
   *
   * @type {IPSEditor}
   * @memberof EditorControllerBase
   */
  public modelService!: IParam;

  /**
   * 是否禁用
   *
   * @type {IPSEditor}
   * @memberof EditorControllerBase
   */
  public disabled: boolean = false;

  /**
   * 应用上下文
   *
   * @type {*}
   * @memberof CtrlControllerBase
   */
  public context: any = {};

  /**
   * 视图参数
   *
   * @type {*}
   * @memberof CtrlControllerBase
   */
  public viewParam: any = {};

  /**
   * 视图参数
   *
   * @type {*}
   * @memberof CtrlControllerBase
   */
  public contextData: any = {};

  /**
   * 编辑器上下文通讯对象
   *
   * @type {*}
   * @memberof CtrlControllerBase
   */
  public contextState: any;

  /**
   * 编辑器值
   *
   * @type {*}
   * @memberof CtrlControllerBase
   */
  public value: any;

  /**
   * 视图钩子对象
   *
   * @type {AppViewHooks}
   * @memberof ViewControllerBase
   */
  public hooks: IAppEditorHooks = new AppEditorHooks();

  /**
   * 模型数据是否加载完成
   *
   * @memberof CtrlControllerBase
   */
  public editorIsLoaded: boolean = false;

  /**
   * 自定义样式的对象
   *
   * @type {*}
   * @memberof EditorBase
   */
  public customStyle: any = {};

  /**
   * 设置自定义props
   *
   * @type {*}
   * @memberof EditorBase
   */
  public customProps: any = {};

  /**
   * 编辑器初始化
   *
   * @memberof EditorControllerBase
   */
  public async editorInit(): Promise<boolean> {
    await this.editorModelInit();
    this.setCustomStyle();
    this.setEditorParams();
    await this.setCustomProps();
    this.editorIsLoaded = true;
    return this.editorIsLoaded;
  }

  /**
   * 编辑器模型初始化
   *
   * @memberof EditorControllerBase
   */
  public async editorModelInit() {
    if (App.isPreviewMode()) {
      return;
    }
    try {
      // 加载编辑器实体
      await (this.editorInstance as any)?.getPSAppDataEntity?.()?.fill();
      // 加载编辑器代码表
      await (this.editorInstance as IPSCodeListEditor)?.getPSAppCodeList?.()?.fill();
    } catch (error) {
      LogUtil.error(error);
    }
  }

  /**
   * 编辑器销毁
   *
   * @public
   * @memberof CtrlControllerBase
   */
  public async editorDestroy() { }

  /**
   * 设置编辑器的自定义高宽
   *
   * @memberof EditorBase
   */
  public setCustomStyle() {
    const { editorWidth, editorHeight } = this.editorInstance;
    this.customStyle = {};
    if (!Util.isEmpty(editorWidth) && editorWidth != 0) {
      this.customStyle.width = editorWidth > 1 ? editorWidth + 'px' : editorWidth * 100 + '%';
    }
    if (!Util.isEmpty(editorHeight) && editorHeight != 0) {
      this.customStyle.height = editorHeight > 1 ? editorHeight + 'px' : editorHeight * 100 + '%';
    }
  }

  /**
   * 设置编辑器导航参数
   *
   * @param keys 编辑器参数key
   * @memberof EditorBase
   */
  public setEditorParams() {
    if (!this.editorInstance.editorParams) {
      return;
    }
    Object.assign(this.customProps, {
      localContext: ModelTool.getNavigateContext(this.editorInstance),
      localParam: ModelTool.getNavigateParams(this.editorInstance),
    });
    Object.assign(this.customProps, {
      modelService: this.modelService
    })
    for (const key in this.editorInstance.editorParams) {
      let param: any;
      if (key == 'uploadparams' || key == 'exportparams' || key == 'readonly') {
        param = eval('(' + this.editorInstance.editorParams[key] + ')');
      } else {
        param = this.editorInstance.editorParams[key];
      }
      if (key.indexOf('.') != -1) {
        const splitArr: Array<any> = key.split('.');
        switch (splitArr[0]) {
          case 'SRFNAVPARAM':
            Object.assign(this.customProps.localParam, { [splitArr[1]]: param });
            break;
          case 'SRFNAVCTX':
            Object.assign(this.customProps.localContext, { [splitArr[1]]: param });
            break;
        }
      } else {
        if (param) {
          this.customProps[key] = Util.parseCustomProp(param);
        }
      }
    }
  }

  /**
   * 设置编辑器的自定义参数
   *
   * @memberof EditorBase
   */
  public async setCustomProps() {
    Object.assign(this.customProps, {
      placeholder: this.editorInstance.placeHolder,
      readonly: this.editorInstance.readOnly,
      name: this.editorInstance.name,
    });
  }

  /**
   * 改变编辑器的值
   *
   * @param {*} value
   * @memberof EditorControllerBase
   */
  public changeValue(value: any) {
    this.hooks.valueChange.callSync({
      arg: {
        name: this.editorInstance.name,
        value: value,
      },
    });
  }
}